import type {
  cut_demand,
  cut_demand_detail,
  cut_demand_sum,
  cut_process,
  cut_propose,
  divide_demand,
  divide_demand_sum,
  stick_propose,
  stick_propose_group
} from '@/types/billdata'
import type {
  pd_board,
  pd_coil,
  pd_location_storage,
  pd_qrcode,
  t_boards_spec_options,
  t_coils_width_options
} from '@/types/producedata'
import { compare_obj, distinct, make_billcode, sum, today } from './common'
import { find_coils_by_width, find_cutsolution } from './dataUtils'
export const groupCutBills = (bills: cut_demand[]) => {
  //通过开料需求进行分组，该分组不同的用料+材质+厚度分到不同的组，其他分组规则可以自定义，可以是按日期或时格（比如3天为一期间），也可以按不同计划部门继续分组
  //分组合并后还有一个应当指的注意的问题，单据合并后可能会产生大单，大单不太适合进行流转，所以可以根据单数或产出数的上限进行继续分组
  const result: cut_demand_sum[] = []
  bills.forEach((item) => {
    let exists = result.find((r) => {
      return (
        r.material_type === item.material_type &&
        r.height === item.height &&
        compare_obj(r.metal, item.metal, 'code') &&
        r.plandept === item.plandept &&
        r.planer === item.planer
      )
    })
    if (!exists) {
      exists = {
        billcode: make_billcode(),
        plan_date: today(),
        plandept: item.plandept,
        planer: item.planer,
        doc_date: today(),
        material_type: item.material_type,
        metal: item.metal,
        height: item.height,
        computed: false,
        details: [],
        supply_width: []
      }
      result.push(exists)
    }
    const detail = JSON.parse(JSON.stringify(item)) as cut_demand_detail
    const cutsolution = find_cutsolution(typeof detail.cut_solution === 'string' ? detail.cut_solution : detail.cut_solution!.cut_code)
    detail.cut_width = cutsolution?.width
    detail.cut_length = cutsolution?.length
    detail.unit_output = cutsolution?.output
    detail.even_offset = cutsolution?.even_offset
    detail.h_offset = cutsolution?.h_offset
    detail.v_offset = cutsolution?.v_offset
    if (detail?.unit_output) detail.all_pattern = Math.ceil(detail.qty / detail!.unit_output)
    exists.details.push(detail)
  })

  result.forEach((r) => {
    r.total_parts = sum(r.details.map((s) => s.qty))
    r.total_pattern = sum(r.details.map((s) => (s.all_pattern ? s.all_pattern : 0)))
    r.mo_count = distinct(r.details.map((s) => s.mocode))?.length
    r.all_demand = distinct(r.details.map((s) => s.billcode))?.length
  })
  return result
}

export const groupDivideBills = (bills: divide_demand[]) => {
  //通过分割需求进行分组，该分组不同的用料+材质+截面分到不同的组，其他分组规则可以自定义，可以是按日期或时格（比如3天为一期间），也可以按不同计划部门继续分组
  //分组合并后还有一个应当指的注意的问题，单据合并后可能会产生大单，大单不太适合进行流转，所以可以根据单数或产出数的上限进行继续分组
  const result: divide_demand_sum[] = []
  bills.forEach((item) => {
    let exists = result.find((r) => {
      return (
        r.material_type === item.material_type &&
        compare_obj(r.section, item.section, 'code') &&
        compare_obj(r.metal, item.metal, 'code') &&
        r.plandept === item.plandept &&
        r.planer === item.planer &&
        r.unit === item.unit
      )
    })
    if (!exists) {
      exists = {
        billcode: make_billcode(),
        plan_date: today(),
        plandept: item.plandept,
        planer: item.planer,
        doc_date: today(),
        material_type: item.material_type,
        metal: item.metal,
        unit: item.unit,
        computed: false,
        divide_detail: [],
        supply_length: [],
        section: item.section
      }
      result.push(exists)
    }
    let group_exists = exists.divide_detail.find((r) => r.length === item.length)
    if (!group_exists) {
      group_exists = { length: item.length, divide_demand_details: [] }
      exists.divide_detail.push(group_exists)
    }
    group_exists.divide_demand_details.push(item)
  })

  result.forEach((r) => {
    r.divide_detail.forEach((s) => {
      s.demand_qty = sum(s.divide_demand_details.map((t) => t.qty))
      s.demand_count = s.divide_demand_details.length
      s.mo_count = distinct(s.divide_demand_details.map((t) => t.mocode))?.length
    })
    r.divide_detail.sort((a, b) => {
      return a.length - b.length
    })
    r.all_demand = sum(r.divide_detail.map((s) => s.demand_count!))
    r.mo_count = sum(r.divide_detail.map((s) => s.mo_count!))
    r.all_length = sum(r.divide_detail.map((s) => s.length * s.demand_qty!))
    r.total_parts = sum(r.divide_detail.map((s) => s.demand_qty!))
  })
  return result
}

export const groupBoard = (board: pd_board[]) => {
  const result: t_boards_spec_options[] = []
  board.forEach((item) => {
    let o = result.find(
      (r) => r.width === item.width && r.metal === item.metal && r.height === item.height && r.height === item.height
    )
    if (!o) {
      o = {
        width: item.width,
        length: item.length,
        metal: typeof item.metal === 'string' ? item.metal : item.metal.code,
        height: item.height,
        qty: item.qty
      }
      result.push(o)
    }
    o.qty += item.qty
  })
  return result
}

export const groupCoils = (coils: pd_coil[]) => {
  const result: t_coils_width_options[] = []
  coils.forEach((item) => {
    let o = result.find((r) => r.width === item.width && r.metal === item.metal && r.height === item.height)
    if (!o) {
      o = {
        width: item.width,
        metal: typeof item.metal === 'string' ? item.metal : item.metal.code,
        height: item.height,
        stock_length: 0,
        stock_pcs: 0
      }
      result.push(o)
    }
    o.stock_length += item.length
    o.stock_pcs += 1
  })
  return result
}

export const groupCutPropose = (cut_process_list: cut_process[]) => {
  const result: cut_propose[] = []
  cut_process_list.forEach((process) => {
    const exist = result.find((r) => r.groupcode === process.groupcode && r.width === process.coil_width)
    if (!exist) {
      result.push({
        propose_code: make_billcode(),
        width: process.coil_width,
        total_coil_length: process.coil_length!,
        groupcode: process.groupcode,
        metal: process.metal,
        total_remainder: process.all_remainder!,
        effective_area: process.effective_area!,
        total_area: process.coil_length! * process.coil_width,
        height: process.height,
        provide_coils: [],
        process: [process],
        match_coils_count: 0,
        total_over_output: process.over_output!,
        total_over_output_area: process.over_output_area!
      })
    } else {
      exist.process.push(process)
      exist.total_remainder += process.all_remainder!
      exist.total_coil_length += process.coil_length!
      exist.effective_area += process.effective_area!
      exist.total_area += process.coil_length! * process.coil_width
      exist.total_over_output += process.over_output!
      exist.total_over_output_area += process.over_output_area!
    }
  })
  result.forEach((r) => {
    r.usage = r.effective_area / r.total_area
    find_coils_by_width(
      r.width,
      r.height,
      typeof r.metal === 'string' ? r.metal : r.metal.code,
      r.total_coil_length / 1000 //实际操作中需要进行单位转换
    ).forEach((c) => {
      r.provide_coils.push(c)
    })
    r.match_coils_count = r.provide_coils.length
    if (r.provide_coils.length > 0) {
      const c = r.provide_coils[0]
      r.use_coil = typeof c === 'string' ? c : c.barcode
    }
  })
  return result
}

export const groupDividePropose = (propose: stick_propose[]) => {
  const group_codes = distinct(propose.map((r) => r.groupcode))
  const result: stick_propose_group[] = []
  group_codes?.forEach((code) => {
    const the_proposes = propose.filter((r) => code === r.groupcode)
    const all_stick: { length: number; qty: number }[] = []
    the_proposes.forEach((r) =>
      r.details.forEach((s) => {
        if (!s.use_remainder_id) {
          const exist = all_stick.find((t) => t.length === s.stick_length)
          if (exist) {
            exist.qty += s.stick_qty
          } else {
            all_stick.push({
              length: s.stick_length,
              qty: s.stick_qty
            })
          }
        }
      })
    )
    const item: stick_propose_group = {
      groupcode: code,
      stick_propose: the_proposes,
      all_stick: all_stick,
      section: the_proposes[0].section,
      metal: the_proposes[0].metal,
      lengths: all_stick.map((r) => r.length).join(',')
    }
    result.push(item)
  })
  return result
}

export const groupQrCode = (qrcodes: pd_qrcode[]) => {
  const result: pd_location_storage[] = []
  qrcodes.forEach((r) => {
    const exists = result.find((s) => compare_obj(s.location, r.location, 'barcode') && compare_obj(s.material, r.material, 'code'))
    if (exists) {
      exists.qty += r.qty
    } else {
      const item = { qty: r.qty, material: r.material, location: r.location }
      result.push(item)
    }
  })
  return result
}
